package com.testlio.assignment.mapper;

import com.testlio.assignment.dto.IssueDTO;
import com.testlio.assignment.dto.CreateIssueRequest;
import com.testlio.assignment.dto.UpdateIssueRequest;
import com.testlio.assignment.model.Issue;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.AfterMapping;
import org.mapstruct.MappingTarget;
import java.time.LocalDateTime;

/**
 * Mapper class to convert between Issue entities and DTOs.
 * Handles the conversion between different object types:
 * - Entity to DTO conversion
 * - CreateRequest to Entity conversion
 * - UpdateRequest to Entity updates
 */
@Mapper(componentModel = "spring")
public interface IssueMapper {

    /**
     * Converts an Issue entity to an IssueDTO.
     * @param issue The Issue entity to convert
     * @return The converted IssueDTO
     */
    IssueDTO toDTO(Issue issue);

    /**
     * Creates a new Issue entity from a CreateIssueRequest.
     * @param request The CreateIssueRequest containing the new issue data
     * @return A new Issue entity (not yet persisted)
     */
    @Mapping(target = "id", ignore = true)
    @Mapping(target = "updatedBy", ignore = true)
    @Mapping(target = "createdAt", expression = "java(java.time.LocalDateTime.now())")
    @Mapping(target = "updatedAt", expression = "java(java.time.LocalDateTime.now())")
    Issue toEntity(CreateIssueRequest request);

    /**
     * Updates an existing Issue entity with data from an UpdateIssueRequest.
     * @param issue The existing Issue entity to update
     * @param request The UpdateIssueRequest containing the new data
     */
    @Mapping(target = "createdAt", ignore = true)
    @Mapping(target = "updatedAt", expression = "java(java.time.LocalDateTime.now())")
    @Mapping(target = "createdBy", ignore = true)
    default void updateEntityFromRequest(Issue issue, UpdateIssueRequest request) {
        if (request.getTitle() != null) {
            issue.setTitle(request.getTitle());
        }
        if (request.getDescription() != null) {
            issue.setDescription(request.getDescription());
        }
        if (request.getUpdatedBy() != null) {
            issue.setUpdatedBy(request.getUpdatedBy());
        }
    }
}
